﻿/* CombatSimForm.cs
 * Author: Richard Broker
 * 
 *  This file is part of Tame.
 *
 *  Tame is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *  
 *  Tame is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with Tame. If not, see <http://www.gnu.org/licenses/>.
*/

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;

/* TODO:
 * http://forum.pardus.at/index.php?showtopic=49961&view=findpost&p=997711 
 * Eng/weap incorporation in SMAAT?
 * */
namespace Tame
{
    public partial class CombatSimForm : Form
    {
        // Variables to import on initialisation.
        string armorName;
        string shipName;
        string shieldName;
        int hullFort;
        int shieldPowering;
        int ENEMY_ID = 1;
        int YOU_ID = 0;
        bool shieldDown = false;
        bool armorDown = false;
        bool hullDown = false;
        bool enemyshieldDown = false;
        bool enemyarmorDown = false;
        bool enemyhullDown = false;
        int roundsDone = 0;

        double hullfortBonus = 1;
        double enemyHullFortBonus = 1;
        double shieldPowbonus = 1;
        double enemyShieldPowBonus = 1;

        int SHIELD_DAMAGE_SUFFERED = 0;
        int ARMOR_DAMAGE_SUFFERED = 0;
        int HULL_DAMAGE_SUFFERED = 0;
        int ENEMY_SHIELD_DAMAGE_SUFFERED = 0;
        int ENEMY_ARMOR_DAMAGE_SUFFERED = 0;
        int ENEMY_HULL_DAMAGE_SUFFERED = 0;
        int OWEAPSPEC = -1;
        int EMWEAPSPEC = -1;
        int CONVWEAPSPEC = -1;

        // Missiles
        int YOU_ROUNDS_SINCE_LAST_MISSILE_FIRED = 0;
        int ENEMY_ROUNDS_SINCE_LAST_MISSILE_FIRED = 0;
        
        int Enemyindex = 0;
        int Youindex = 0;
        int enemyGunLimit = 0;
        int YouGunLimit = 0;

        string[] GUNS_ARRAY;

        DrawingFunctions drawing = new DrawingFunctions();
        Ship playerShip = new Ship();
        Armor ArmorClass = new Armor();
        Equipment shipEquipment = new Equipment();
        Guns shipGuns = new Guns();

        SolidBrush hullBrush = new SolidBrush(Color.Blue);
        SolidBrush lightGrayBrush = new SolidBrush(Color.LightGray);
        SolidBrush sizeBrush = new SolidBrush(Color.Red);
        SolidBrush shieldBrush = new SolidBrush(Color.Purple);
        SolidBrush armorBrush = new SolidBrush(Color.Green);
        SolidBrush whiteBrush = new SolidBrush(Color.White);
        SolidBrush orangeBrush = new SolidBrush(Color.Orange);
        SolidBrush greenBrush = new SolidBrush(Color.Green);
        SolidBrush redBrush = new SolidBrush(Color.Red);
        SolidBrush yellowBrush = new SolidBrush(Color.Yellow);
        SolidBrush standardHullBrush;
        SolidBrush standardArmorBrush;
        SolidBrush standardShieldBrush;
        SolidBrush enemyHullBrush;
        SolidBrush enemyArmorBrush;
        SolidBrush enemyShieldBrush;

        public CombatSimForm(string shipName_con, string shieldName_con, string armorName_con, int hullFort_con, int shieldPowering_con, string[] gunsArray, int oWeapSpec, int emWeapSpec, int convWeapSpec)
        {
            InitializeComponent();
            shipName = shipName_con;
            shieldName = shieldName_con;
            armorName = armorName_con;
            hullFort = hullFort_con;
            shieldPowering = shieldPowering_con;
            GUNS_ARRAY = gunsArray;
            OWEAPSPEC = oWeapSpec;
            EMWEAPSPEC = emWeapSpec;
            CONVWEAPSPEC = convWeapSpec;
        }
        
        private void removeGunButton_Click(object sender, EventArgs e)
        {
            if (Youindex > 0)
            {
                weaponDataGrid.Rows.Remove(weaponDataGrid.Rows[Youindex - 1]);
                Youindex--;
            }
        }

        private void addGunButton_Click(object sender, EventArgs e)
        {
            if ((Youindex <= 4) && (Youindex < YouGunLimit))
            {
                weaponDataGrid.Rows.Add(1);
                weaponDataGrid.Rows[Youindex].Cells[0].Value = GunSelectionComboBox.Text;
                Youindex++;
            }
        }

        private void enemyRemoveGunButton_Click(object sender, EventArgs e)
        {
            if (Enemyindex > 0)
            {

                enemyWeaponDatagrid.Rows.Remove(enemyWeaponDatagrid.Rows[Enemyindex - 1]);
                Enemyindex--;
            }
        }

        private void enemyAddGunButton_Click(object sender, EventArgs e)
        {
            if ((Enemyindex < enemyGunLimit) && (Enemyindex <= 4))
            {
                enemyWeaponDatagrid.Rows.Add(1);
                enemyWeaponDatagrid.Rows[Enemyindex].Cells[0].Value = enemyGunSelectBox.Text;
                Enemyindex++;
            }
        }

        private void multiplierComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            resetCombatSim();
            ScreenRefresh();
        }

        private void enemyMultiplierComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            resetCombatSim();
            ScreenRefresh();
        }

        private void enemyArmorComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {

            if ((enemyArmorComboBox.Text == "Organic") || (enemyArmorComboBox.Text == "Electro-Magnetic"))
            {
                enemyMultiplierComboBox.Items.Remove("1");
                enemyMultiplierComboBox.Items.Remove("6");
            }
            else
            {
                if (enemyMultiplierComboBox.Items.Contains("6") != true)
                {
                    enemyMultiplierComboBox.Items.Add("6");
                }
                if (enemyMultiplierComboBox.Items.Contains("1") != true)
                {
                    enemyMultiplierComboBox.Items.Add("1");
                }
                // Make sure items are in correct order when put back into the combo.
                enemyMultiplierComboBox.Sorted = true;
            }
            if (enemyMultiplierComboBox.SelectedIndex == -1)
            {
                enemyMultiplierComboBox.SelectedIndex = 0;
            }
            resetCombatSim();
            ScreenRefresh();
        }
        private void ArmorComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if ((ArmorComboBox.Text == "Organic") || (ArmorComboBox.Text == "Electro-Magnetic"))
            {
                multiplierComboBox.Items.Remove("1");
                multiplierComboBox.Items.Remove("6");
            }
            else
            {
                if (multiplierComboBox.Items.Contains("6") != true)
                {
                    multiplierComboBox.Items.Add("6");
                }
                if (multiplierComboBox.Items.Contains("1") != true)
                {
                    multiplierComboBox.Items.Add("1");
                }
                // Make sure items are in correct order when put back into the combo.
                multiplierComboBox.Sorted = true;
            }
            if (multiplierComboBox.SelectedIndex == -1)
            {
                multiplierComboBox.SelectedIndex = 0;
            }
            resetCombatSim();
            ScreenRefresh();
        }

        // Fancy Pie Charts
        private void DrawArmorPieCharts()
        {
            // To format as %, value is multiplied by 100.
            float efficiency = 0;
            float degreesVsConv;
            float degreesVsEM;
            float degreesVsOrg;
            float degreesVsPardus;
            float pieSize = 49;
            float boxSize = 52;

            Graphics drawArmorPieChartvsConv = enemyGunVsYourArmor.CreateGraphics();
                drawArmorPieChartvsConv.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            Graphics drawArmorPieChartvsORG = enemyArmorVsYourGuns.CreateGraphics();
                drawArmorPieChartvsORG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            Graphics drawArmorPieChartvsEM = yourGunsVsEnemyArmor.CreateGraphics();
                drawArmorPieChartvsEM.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

            Graphics drawArmorPieChartvsPardus = yourArmorvsEnemyGuns.CreateGraphics();
                drawArmorPieChartvsPardus.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

            if (ArmorComboBox.Text == "Conventional")
            {
                efficiency = 100;
                convEfficiencyLabel.Text = efficiency.ToString("N0") + "%";
                degreesVsConv = drawing.ConvertEfficiencyToDegrees(ref efficiency);
                drawArmorPieChartvsConv.FillRectangle(lightGrayBrush, 0, 0, boxSize, boxSize);
                drawArmorPieChartvsConv.FillPie(orangeBrush, 0, 0, pieSize, pieSize, 0, degreesVsConv);

                efficiency = 100;
                orgEfficiencyLabel.Text = efficiency.ToString("N0") + "%";
                degreesVsOrg = drawing.ConvertEfficiencyToDegrees(ref efficiency);
                drawArmorPieChartvsORG.FillRectangle(lightGrayBrush, 0, 0, boxSize, boxSize);
                drawArmorPieChartvsORG.FillPie(orangeBrush, 0, 0, pieSize, pieSize, 0, degreesVsOrg);

                efficiency = 110;
                emEfficiencyLabel.Text = efficiency.ToString("N0") + "%";
                degreesVsEM = drawing.ConvertEfficiencyToDegrees(ref efficiency);
                drawArmorPieChartvsEM.FillRectangle(lightGrayBrush, 0, 0, boxSize, boxSize);
                drawArmorPieChartvsEM.FillPie(redBrush, 0, 0, pieSize, pieSize, 0, degreesVsEM);

                efficiency = 100;
                pardusEfficiencyLabel.Text = efficiency.ToString("N0") + "%";
                degreesVsPardus = drawing.ConvertEfficiencyToDegrees(ref efficiency);
                drawArmorPieChartvsPardus.FillRectangle(lightGrayBrush, 0, 0, boxSize, boxSize);
                drawArmorPieChartvsPardus.FillPie(orangeBrush, 0, 0, pieSize, pieSize, 0, degreesVsPardus);
            }

            if (ArmorComboBox.Text == "")
            {
                convEfficiencyLabel.Text = "0%";
                drawArmorPieChartvsConv.FillRectangle(lightGrayBrush, 0, 0, boxSize, boxSize);

                orgEfficiencyLabel.Text = "0%";
                drawArmorPieChartvsORG.FillRectangle(lightGrayBrush, 0, 0, boxSize, boxSize);

                emEfficiencyLabel.Text = "0%";
                drawArmorPieChartvsEM.FillRectangle(lightGrayBrush, 0, 0, boxSize, boxSize);

                pardusEfficiencyLabel.Text = "0%";
                drawArmorPieChartvsPardus.FillRectangle(lightGrayBrush, 0, 0, boxSize, boxSize);
            }
            if (ArmorComboBox.Text == "Organic")
            {
                efficiency = 60;
                convEfficiencyLabel.Text = efficiency.ToString("N0") + "%";
                degreesVsConv = drawing.ConvertEfficiencyToDegrees(ref efficiency);
                drawArmorPieChartvsConv.FillRectangle(lightGrayBrush, 0, 0, boxSize, boxSize);
                drawArmorPieChartvsConv.FillPie(greenBrush, 0, 0, pieSize, pieSize, 0, degreesVsConv);

                efficiency = 50;
                orgEfficiencyLabel.Text = efficiency.ToString("N0") + "%";
                degreesVsOrg = drawing.ConvertEfficiencyToDegrees(ref efficiency);
                drawArmorPieChartvsORG.FillRectangle(lightGrayBrush, 0, 0, boxSize, boxSize);
                drawArmorPieChartvsORG.FillPie(greenBrush, 0, 0, pieSize, pieSize, 0, degreesVsOrg);

                efficiency = 125;
                emEfficiencyLabel.Text = efficiency.ToString("N0") + "%";
                degreesVsEM = drawing.ConvertEfficiencyToDegrees(ref efficiency);
                drawArmorPieChartvsEM.FillRectangle(lightGrayBrush, 0, 0, boxSize, boxSize);
                drawArmorPieChartvsEM.FillPie(redBrush, 0, 0, pieSize, pieSize, 0, degreesVsEM);

                efficiency = 100;
                pardusEfficiencyLabel.Text = efficiency.ToString("N0") + "%";
                degreesVsPardus = drawing.ConvertEfficiencyToDegrees(ref efficiency);
                drawArmorPieChartvsPardus.FillRectangle(lightGrayBrush, 0, 0, boxSize, boxSize);
                drawArmorPieChartvsPardus.FillPie(orangeBrush, 0, 0, pieSize, pieSize, 0, degreesVsPardus);
            }

            if (ArmorComboBox.Text == "Electro-Magnetic")
            {
                efficiency = 60;
                convEfficiencyLabel.Text = efficiency.ToString("N0") + "%";
                degreesVsConv = drawing.ConvertEfficiencyToDegrees(ref efficiency);
                drawArmorPieChartvsConv.FillRectangle(lightGrayBrush, 0, 0, boxSize, boxSize);
                drawArmorPieChartvsConv.FillPie(greenBrush, 0, 0, pieSize, pieSize, 0, degreesVsConv);

                efficiency = 100;
                orgEfficiencyLabel.Text = efficiency.ToString("N0") + "%";
                degreesVsOrg = drawing.ConvertEfficiencyToDegrees(ref efficiency);
                drawArmorPieChartvsORG.FillRectangle(lightGrayBrush, 0, 0, boxSize, boxSize);
                drawArmorPieChartvsORG.FillPie(orangeBrush, 0, 0, pieSize, pieSize, 0, degreesVsOrg);

                efficiency = 50;
                emEfficiencyLabel.Text = efficiency.ToString("N0") + "%";
                degreesVsEM = drawing.ConvertEfficiencyToDegrees(ref efficiency);
                drawArmorPieChartvsEM.FillRectangle(lightGrayBrush, 0, 0, boxSize, boxSize);
                drawArmorPieChartvsEM.FillPie(greenBrush, 0, 0, pieSize, pieSize, 0, degreesVsEM);

                efficiency = 125;
                pardusEfficiencyLabel.Text = efficiency.ToString("N0") + "%";
                degreesVsPardus = drawing.ConvertEfficiencyToDegrees(ref efficiency);
                drawArmorPieChartvsPardus.FillRectangle(lightGrayBrush, 0, 0, boxSize, boxSize);
                drawArmorPieChartvsPardus.FillPie(redBrush, 0, 0, pieSize, pieSize, 0, degreesVsPardus);
            }
            if (ArmorComboBox.Text == "Pardus")
            {
                efficiency = 45;
                convEfficiencyLabel.Text = efficiency.ToString("N0") + "%";
                degreesVsConv = drawing.ConvertEfficiencyToDegrees(ref efficiency);
                drawArmorPieChartvsConv.FillRectangle(lightGrayBrush, 0, 0, boxSize, boxSize);
                drawArmorPieChartvsConv.FillPie(greenBrush, 0, 0, pieSize, pieSize, 0, degreesVsConv);

                efficiency = 55;
                orgEfficiencyLabel.Text = efficiency.ToString("N0") + "%";
                degreesVsOrg = drawing.ConvertEfficiencyToDegrees(ref efficiency);
                drawArmorPieChartvsORG.FillRectangle(lightGrayBrush, 0, 0, boxSize, boxSize);
                drawArmorPieChartvsORG.FillPie(greenBrush, 0, 0, pieSize, pieSize, 0, degreesVsOrg);

                efficiency = 75;
                emEfficiencyLabel.Text = efficiency.ToString("N0") + "%";
                degreesVsEM = drawing.ConvertEfficiencyToDegrees(ref efficiency);
                drawArmorPieChartvsEM.FillRectangle(lightGrayBrush, 0, 0, boxSize, boxSize);
                drawArmorPieChartvsEM.FillPie(greenBrush, 0, 0, pieSize, pieSize, 0, degreesVsEM);

                efficiency = 100;
                pardusEfficiencyLabel.Text = efficiency.ToString("N0") + "%";
                degreesVsPardus = drawing.ConvertEfficiencyToDegrees(ref efficiency);
                drawArmorPieChartvsPardus.FillRectangle(lightGrayBrush, 0, 0, boxSize, boxSize);
                drawArmorPieChartvsPardus.FillPie(orangeBrush, 0, 0, pieSize, pieSize, 0, degreesVsPardus);
            }

        }

        private double DetermineGunDamageOutput(int ID)
        {
            int i,j,k;
            double tempDamage;
            int fireRate;
            double shots = 0;
            int gunType = -1;
            int gunNumber = 0;
            double[] shotHistory = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // Enough spaces for 5 gatlings, 3 shots each.
            double totalDamage = 0 ;
            int modeDamage =0;
            int modeFireRate = 1;
            int limit = -1;
            double gunEfficiency = 0;
            double hitRatio = 0;
            bool useWeapSpec = false;
            ComboBox comboCake;
            DataGridView gridCake;
            
            if (ID == YOU_ID)
            {
            gridCake = weaponDataGrid;            
            comboCake = enemyArmorComboBox;
            limit = YouGunLimit;
            hitRatio = double.Parse(yourHitRatioTextBox.Text);
            if (youUseWeapSpecCheckBox.Checked == true)
            {
                useWeapSpec = true;
            }
             
            }
            else
            {
                gridCake = enemyWeaponDatagrid;
                comboCake = ArmorComboBox;
                limit = enemyGunLimit;
                hitRatio = double.Parse(enemyHitRatioTextBox.Text);
                if (enemyUseWeapSpecCheckBox.Checked == true)
                {
                    useWeapSpec = true;
                }
            }

            k = 0;

            for (i = 0; i < gridCake.RowCount; i++ )
            {
                gunNumber = shipGuns.determineGunNunmber(gridCake.Rows[i].Cells[0].Value.ToString());
                gunType = shipGuns.determineGunType(gunNumber);
                gunEfficiency = shipGuns.determineGunEfficiency(gunType, false, -1, comboCake);
                
               tempDamage = shipGuns.GetGunData(ref modeDamage, (gridCake.Rows[i].Cells[0].Value.ToString()));
               tempDamage = (tempDamage / 100) * gunEfficiency;
               fireRate = shipGuns.GetGunData(ref modeFireRate, (gridCake.Rows[i].Cells[0].Value.ToString()));
               
                // Add weapon spec:
               if (useWeapSpec == true)
               {
                   tempDamage = shipGuns.determineGunDamageWithWeapSpec(tempDamage, gunType, CONVWEAPSPEC, OWEAPSPEC, EMWEAPSPEC);
               }

               // Accumulate number of shots taken:
               shots += fireRate;
               for (j = 0; j < fireRate; j++)
               {
                   shotHistory[k] = tempDamage;
                   k++;
               }              
            }
            // Add the remaining shots on to the total damage and give it out:
            totalDamage = (shotHistory[0] + shotHistory[1] + shotHistory[2] + shotHistory[3] + shotHistory[4] + shotHistory[5] + shotHistory[6] + shotHistory[7] + shotHistory[8] + shotHistory[9] + shotHistory[10] + shotHistory[11] + shotHistory[12] + shotHistory[13] + shotHistory[14]);        

            // Take into account hit ratio:
            totalDamage = Math.Ceiling(((totalDamage / 100) * hitRatio));
            return totalDamage;
        }

        private void DetermineIfMissileIsToBeFired()
        {
            int modeART = 0;
            int ART;
            int FIREMISSILE = 0;
            int FIREMISSILEBOTH = 0;

            // Get missile from you - test if it's "you_rounds_since_last_missile_fired" is >= its ART.
            // if so - set FIREMISSILE = 1;

            // Get next missile for enemy - do the same ART test.
            // if so - set... oh you get the idea return FIREMISSILE = 2;

            // If FIREMISSILE == 1 && FIREMISSILE == 2 return FIREMISSILE = 3;
            // return FIREMISSILE
        }

        private int determineGunTypeFromGrid(int ID, int index)
        {
            DataGridView gridCake;
            int gunNumber = -1;
            int gunType = -1;

            if (ID == YOU_ID)
            {
                gridCake = weaponDataGrid;
            }
            else
            {
                gridCake = enemyWeaponDatagrid;
            }

            try
            {
                gunNumber = shipGuns.determineGunNunmber(gridCake.Rows[index].Cells[0].Value.ToString());
                gunType = shipGuns.determineGunType(gunNumber);
            }
            catch
            {
            }

              return gunType;
        }


        private void SmaatForm_Paint(object sender, PaintEventArgs e)
        {
            DrawArmorPieCharts();
            ScreenRefresh();
        }

        private void enemyHitRatioTrackBar_Scroll(object sender, EventArgs e)
        {
            double hitRatio = 0.0;
            hitRatio = enemyHitRatioTrackBar.Value;
            hitRatio = (hitRatio / 100.0);
            enemyHitRatioTextBox.Text = hitRatio.ToString();
        }
        private void yourHitRatioTrackBar_Scroll(object sender, EventArgs e)
        {
            double hitRatio = 0.0;
            hitRatio = yourHitRatioTrackBar.Value;
            hitRatio = (hitRatio / 100.0);
            yourHitRatioTextBox.Text = hitRatio.ToString();
        }

        private void estimatedHitRatioTextBox_TextChanged(object sender, EventArgs e)
        {
            double HitRatio = 0;
            try
            {
                if (Regex.IsMatch(enemyHitRatioTextBox.Text, "[0-9.,]"))
                {
                    HitRatio = double.Parse(enemyHitRatioTextBox.Text);

                    if (HitRatio <= 100)
                    {
                        enemyHitRatioTrackBar.Value = (int)(HitRatio * 100.0);
                    }
                    else
                    {
                        enemyHitRatioTrackBar.Value = 1000;
                        enemyHitRatioTextBox.Text = "100";
                    }
                }
                else
                {
                    enemyHitRatioTrackBar.Value = 0;
                }
            }
            catch (Exception)
            {
                enemyHitRatioTrackBar.Value = 0;
            }
        }

        private void yourHitRatioTextBox_TextChanged(object sender, EventArgs e)
        {
            double HitRatio = 0;
            try
            {
                if (Regex.IsMatch(yourHitRatioTextBox.Text, "[0-9.,]"))
                {
                    HitRatio = double.Parse(yourHitRatioTextBox.Text);

                    if (HitRatio <= 100)
                    {
                        yourHitRatioTrackBar.Value = (int)(HitRatio * 100.0);
                    }
                    else
                    {
                        yourHitRatioTrackBar.Value = 1000;
                        yourHitRatioTextBox.Text = "100";
                    }
                }
                else
                {
                    yourHitRatioTrackBar.Value = 0;
                }
            }
            catch (Exception)
            {
                yourHitRatioTrackBar.Value = 0;
            }
        }

        private void DrawStandardBar(ref int value, Panel panel, SolidBrush brush)
        {
            int x = (250 - value);

            Graphics drawShipBar = panel.CreateGraphics();
            drawShipBar.FillRectangle(whiteBrush, value, 0, x, 10);
            drawShipBar.FillRectangle(brush, 0, 0, value, 10);
        }

        private void ScreenRefresh()
        {
            int shipArmor;
            int shipHull;
            int shieldPoints;
            int enemyshipArmor;
            int enemyshipHull;
            int enemyshieldPoints;
            int modeArmor = 4;
            int modeHull = 5;
            int modePoints = 0;
            double hullfortBonus = 1;
            double enemyHullFortBonus = 1;
            double shieldPowBonus = 1;
            double enemyShieldPowBonus = 1;

            #region hullfort/sp bonuses
            if (hullFortComboBox.SelectedIndex == 1)
            {
                hullfortBonus = 1.2;
            }
            if (hullFortComboBox.SelectedIndex == 2)
            {
                hullfortBonus = 1.4;
            }
            if (enemyHullFortComboBox.SelectedIndex == 1)
            {
                enemyHullFortBonus = 1.2;
            }
            if (enemyHullFortComboBox.SelectedIndex == 2)
            {
                enemyHullFortBonus = 1.4;
            }
            if (shieldPoweringComboBox.SelectedIndex == 1)
            {
                shieldPowBonus = 1.25;
            }
            if (shieldPoweringComboBox.SelectedIndex == 2)
            {
                shieldPowBonus = 1.5;
            }
            if (enemyShieldPoweringComboBox.SelectedIndex == 1)
            {
                shieldPowBonus = 1.25;
            }
            if (enemyShieldPoweringComboBox.SelectedIndex == 2)
            {
                shieldPowBonus = 1.5;
            }
            #endregion

            // Player (you)
            shipArmor = playerShip.GetShipData(ref modeArmor, shipSelectBox.Text);
            shipHull = playerShip.GetShipData(ref modeHull, shipSelectBox.Text);
            shieldPoints = shipEquipment.GetShieldData(ref modePoints, shieldSelectComboBox.Text);

            // Enemy
            enemyshipArmor = playerShip.GetShipData(ref modeArmor, enemyShipComboBox.Text);
            enemyshipHull = playerShip.GetShipData(ref modeHull, enemyShipComboBox.Text);
            enemyshieldPoints = shipEquipment.GetShieldData(ref modePoints, EnemyShieldComboBox.Text);

            // Do labels for you BEFORE scaling down:
            hullPointsNumericalLabel.Text = string.Format("{0}/{1} ({2})", (shipHull - HULL_DAMAGE_SUFFERED), shipHull, ((shipHull - HULL_DAMAGE_SUFFERED) * hullfortBonus));
            enemyHullLabel.Text = string.Format("{0}/{1} ({2})", (enemyshipHull - ENEMY_HULL_DAMAGE_SUFFERED), enemyshipHull, ((enemyshipHull - ENEMY_HULL_DAMAGE_SUFFERED) * enemyHullFortBonus));
            shieldPointsNumericalLabel.Text = string.Format("{0}/{1} ({2})", (shieldPoints- SHIELD_DAMAGE_SUFFERED), shieldPoints, ((shieldPoints - SHIELD_DAMAGE_SUFFERED) * shieldPowBonus));
            enemyShieldLabel.Text = string.Format("{0} ({1})", (enemyshieldPoints - ENEMY_SHIELD_DAMAGE_SUFFERED), enemyshieldPoints, ((enemyshieldPoints - ENEMY_SHIELD_DAMAGE_SUFFERED) * enemyShieldPowBonus));
            armorPointsNumericalLabel.Text = string.Format("{0}/{1} ({2})", (shipArmor - ARMOR_DAMAGE_SUFFERED), shipArmor, ((shipArmor - ARMOR_DAMAGE_SUFFERED) * (multiplierComboBox.SelectedIndex + 1)));
            enemyArmorLabel.Text = string.Format("{0}/{1} ({2})", (enemyshipArmor - ENEMY_ARMOR_DAMAGE_SUFFERED), enemyshipArmor,((enemyshipArmor - ENEMY_ARMOR_DAMAGE_SUFFERED) * (enemyMultiplierComboBox.SelectedIndex + 1)));

            // Scale data values to fit bar as many are over "250"
            shipArmor = ((shipArmor - ARMOR_DAMAGE_SUFFERED) / 4);
            shipHull = ((shipHull - HULL_DAMAGE_SUFFERED) / 4);
            shieldPoints = ((shieldPoints - SHIELD_DAMAGE_SUFFERED) / 4);

            // Enemy
            enemyshipArmor = ((enemyshipArmor - ENEMY_ARMOR_DAMAGE_SUFFERED) / 4);
            enemyshipHull = ((enemyshipHull - ENEMY_HULL_DAMAGE_SUFFERED) / 4);
            enemyshieldPoints = ((enemyshieldPoints - ENEMY_SHIELD_DAMAGE_SUFFERED) / 4);

            // You
            DrawStandardBar(ref shipArmor, shipArmorPanel, standardArmorBrush);
            DrawStandardBar(ref shipHull, shipHullPanel, standardHullBrush);
            DrawStandardBar(ref shieldPoints, shipShieldPanel, standardShieldBrush);

            // Enemy
            DrawStandardBar(ref enemyshipArmor, enemyArmorPanel, enemyArmorBrush);
            DrawStandardBar(ref enemyshipHull, enemyHullPanel, enemyHullBrush);
            DrawStandardBar(ref enemyshieldPoints, enemyShieldPanel, enemyShieldBrush);
        }

        private void shipSelectBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            int modeGunMounts = 1;
            YouGunLimit = playerShip.GetShipData(ref modeGunMounts, shipSelectBox.Text); // Get gun mounts

            while (YouGunLimit < Youindex)
            {
                // Remove excess guns.
                    weaponDataGrid.Rows.Remove(weaponDataGrid.Rows[Youindex - 1]);
                    Youindex--;
            }
            resetCombatSim();
            ScreenRefresh();
        }


        private void enemyShipComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            int modeGunMounts = 1;
            enemyGunLimit = playerShip.GetShipData(ref modeGunMounts, enemyShipComboBox.Text); // Get gun mounts

            while (enemyGunLimit < Enemyindex)
            {
                // Remove excess guns.
                enemyWeaponDatagrid.Rows.Remove(enemyWeaponDatagrid.Rows[Enemyindex - 1]);
                Enemyindex--;
            }
            resetCombatSim();
            ScreenRefresh();
        }

        private void importFromDesignerButton_Click(object sender, EventArgs e)
        {
            shipSelectBox.Text = shipName;
            ArmorComboBox.Text = ArmorClass.convertArmorNameToType(armorName);
            multiplierComboBox.Text = ArmorClass.convertArmorNameToStrength(armorName).ToString();
            shieldSelectComboBox.Text = shieldName;
            hullFortComboBox.SelectedIndex = hullFort;
            shieldPoweringComboBox.SelectedIndex = shieldPowering;
            int i;
            try
            {
                for (i = 0; i < GUNS_ARRAY.Length; i++)
                {
                    if ((GUNS_ARRAY[i] != "") && (GUNS_ARRAY[i] != ":: None ::") && (GUNS_ARRAY[i] != ":: Normal Guns ::") && (GUNS_ARRAY[i] != ":: Empire Guns ::") && (GUNS_ARRAY[i] != ":: Organic ::") && (GUNS_ARRAY[i] != ":: Electro-Magnetic ::") && (GUNS_ARRAY[i] != ":: Pardus ::"))
                    {
                        if ((Youindex <= 4) && (Youindex < YouGunLimit))
                        {
                            weaponDataGrid.Rows.Add(1);
                            weaponDataGrid.Rows[i].Cells[0].Value = GUNS_ARRAY[i];
                            Youindex++;
                        }
                    }
                }
            }
            catch (Exception)
            {
                while (Youindex > 0)
                {
                    weaponDataGrid.Rows.Remove(weaponDataGrid.Rows[Youindex - 1]);
                    Youindex--;
                }
            }

        }

        private int CalculateShieldStrength(int ID)
        {
            ComboBox shieldBox;
            ComboBox shieldPowBox;
            int modePoints =0;
            int totalHP = 0;

            if (ID == ENEMY_ID)
            {
                shieldBox = EnemyShieldComboBox;
                shieldPowBox = enemyShieldPoweringComboBox;
            }
            else
            {
                 shieldBox = shieldSelectComboBox;
                 shieldPowBox = shieldPoweringComboBox;
            }
            totalHP = shipEquipment.GetShieldData(ref modePoints, shieldBox.Text);
            return totalHP;
        }

        private int CalculateHullStrength(int ID)
        {
            ComboBox hullFortBox;
            ComboBox shipbox;
            int totalStrength;
            int mode = 5;

            if (ID == YOU_ID)
            {
                hullFortBox = hullFortComboBox;
                shipbox = shipSelectBox;
            }
            else
            {
                hullFortBox = enemyHullFortComboBox;
                shipbox = enemyShipComboBox;
            }

            totalStrength = playerShip.GetShipData(ref mode, shipbox.Text);

            return totalStrength;

        }


        private void doCombatButton_Click(object sender, EventArgs e)
        {
            int combatRoundsToDo = int.Parse(numberOfRoundsComboBox.Text);
            int i;
            for (i = 0; i < combatRoundsToDo; i++)
            {
                if ((hullDown == false) && (enemyhullDown == false))
                {
                    doCombat();
                    roundsDone++;

                    // Increment missile round counter - to be reset in missile firing function if a missile is fired.
                    ENEMY_ROUNDS_SINCE_LAST_MISSILE_FIRED++;
                    YOU_ROUNDS_SINCE_LAST_MISSILE_FIRED++;

                }
            }

        }

        private void doCombat()
        {
            int mode = 4;
            int modePoints = 0;
            int modeHull = 5;
            bool youRollover = false;
            bool enemyRollover = false;
            int baseShield = shipEquipment.GetShieldData(ref modePoints, shieldSelectComboBox.Text);
            int baseHull = playerShip.GetShipData(ref modeHull, shipSelectBox.Text);
            int baseArmor = playerShip.GetShipData(ref mode, shipSelectBox.Text);
            int enemyBaseShield = shipEquipment.GetShieldData(ref modePoints, EnemyShieldComboBox.Text);
            int enemyBaseHull = playerShip.GetShipData(ref modeHull, enemyShipComboBox.Text);
            int enemyBaseArmor = playerShip.GetShipData(ref mode, enemyShipComboBox.Text);
            int yourRawDamage = (int) DetermineGunDamageOutput(YOU_ID);
            int enemyRawDamage = (int) DetermineGunDamageOutput(ENEMY_ID);
            int shieldStrength = CalculateShieldStrength(YOU_ID) - SHIELD_DAMAGE_SUFFERED;
            int enemyShieldStrength = CalculateShieldStrength(ENEMY_ID) - ENEMY_SHIELD_DAMAGE_SUFFERED;
            int hullStrength = CalculateHullStrength(YOU_ID) - HULL_DAMAGE_SUFFERED;
            int enemyhullstrength = CalculateHullStrength(ENEMY_ID) - ENEMY_HULL_DAMAGE_SUFFERED;
            int armorStrength = playerShip.GetShipData(ref mode, shipSelectBox.Text) - ARMOR_DAMAGE_SUFFERED;
            int enemyarmorStrength = playerShip.GetShipData(ref mode, enemyShipComboBox.Text)  - ENEMY_ARMOR_DAMAGE_SUFFERED;

            // ***********
            // You
            // ***********
            if (enemyhullDown != true)
            {
                if (shieldDown != true)
                {
                    SHIELD_DAMAGE_SUFFERED += (int)(enemyRawDamage * shieldPowbonus);

                    if (SHIELD_DAMAGE_SUFFERED > baseShield)
                    {
                        shieldDown = true;
                        // Excess shield damage rolls over onto armor:
                        ARMOR_DAMAGE_SUFFERED = (SHIELD_DAMAGE_SUFFERED - baseShield) / int.Parse(multiplierComboBox.Text);
                        SHIELD_DAMAGE_SUFFERED = baseShield;
                        youRollover = true;
                    }
                }
                if ((armorDown != true) && (shieldDown == true) || (youRollover == true))
                {
                    ARMOR_DAMAGE_SUFFERED += (enemyRawDamage / int.Parse(multiplierComboBox.Text));
                    youRollover = false;
                    if (ARMOR_DAMAGE_SUFFERED > baseArmor)
                    {
                        armorDown = true;
                        // Roll over armor damage to hull
                        HULL_DAMAGE_SUFFERED = (int) ((ARMOR_DAMAGE_SUFFERED - baseArmor) * hullfortBonus);
                        ARMOR_DAMAGE_SUFFERED = baseArmor;
                        youRollover = true;
                    }
                }
                if ((hullDown != true) && (armorDown == true) && (shieldDown == true) || (youRollover == true))
                {
                    HULL_DAMAGE_SUFFERED += (int)(enemyRawDamage * hullfortBonus);
                    if (HULL_DAMAGE_SUFFERED > baseHull)
                    {
                        HULL_DAMAGE_SUFFERED = baseHull;
                        hullDown = true;
                    }
                }
            }
            if (hullDown == true)
            {
                MessageBox.Show(string.Format("You have died. Reset the simulation to try again. You lasted {0} Rounds.", roundsDone + 1), "You're down");
            }

            // ********
            // Enemy
            // ********
            if (hullDown == false)
            {
                if (enemyshieldDown != true)
                {
                    ENEMY_SHIELD_DAMAGE_SUFFERED += (int)(yourRawDamage * enemyShieldPowBonus);

                    if (ENEMY_SHIELD_DAMAGE_SUFFERED > enemyBaseShield)
                    {
                        enemyshieldDown = true;
                        // Excess shield damage rolls over onto armor:
                        ENEMY_ARMOR_DAMAGE_SUFFERED = (ENEMY_SHIELD_DAMAGE_SUFFERED - enemyBaseShield) / int.Parse(enemyMultiplierComboBox.Text);
                        ENEMY_SHIELD_DAMAGE_SUFFERED = enemyBaseShield;
                        enemyRollover = true;
                    }
                }
                if ((enemyarmorDown != true) && (enemyshieldDown == true) || (enemyRollover == true))
                {
                    ENEMY_ARMOR_DAMAGE_SUFFERED += (yourRawDamage / int.Parse(enemyMultiplierComboBox.Text));
                    enemyRollover = false;
                    if (ENEMY_ARMOR_DAMAGE_SUFFERED > enemyBaseArmor)
                    {
                        enemyarmorDown = true;
                        // Roll over armor damage to hull
                        ENEMY_HULL_DAMAGE_SUFFERED = (int) ((ENEMY_ARMOR_DAMAGE_SUFFERED - enemyBaseArmor) * enemyHullFortBonus);
                        ENEMY_ARMOR_DAMAGE_SUFFERED = enemyBaseArmor;
                        enemyRollover = true;
                    }
                }
                if ((enemyhullDown != true) && (enemyarmorDown == true) && (enemyshieldDown == true) || (enemyRollover == true))
                {
                    ENEMY_HULL_DAMAGE_SUFFERED += (int)(yourRawDamage * enemyHullFortBonus);
                    if (ENEMY_HULL_DAMAGE_SUFFERED > enemyBaseHull)
                    {
                        ENEMY_HULL_DAMAGE_SUFFERED = enemyBaseHull;
                        enemyhullDown = true;
                    }
                }
            }
            if (enemyhullDown == true)
            {
                MessageBox.Show(string.Format("The Enemy has been defeated! They survived {0} rounds against you.", roundsDone + 1), "Enemy Down");
            }
            #region colourChanges
            // Do colour changes:
            if ((hullStrength < (baseHull * 0.75)) && (hullStrength >= (baseHull * 0.25)))
            {
                standardHullBrush = orangeBrush;
            }
            if (hullStrength < (baseHull * 0.25))
            {
                standardHullBrush = redBrush;
            }
            if ((armorStrength < (baseArmor * 0.75)) && (armorStrength >= (baseArmor * 0.25)))
            {
                standardArmorBrush = orangeBrush;
            }
            if (armorStrength < (baseArmor * 0.25))
            {
                standardArmorBrush = redBrush;
            }
            if ((shieldStrength < (baseShield * 0.75)) && (shieldStrength >= (baseShield * 0.25)))
            {
                standardShieldBrush = orangeBrush;
            }
            if (shieldStrength < (baseShield * 0.25))
            {
                standardShieldBrush = redBrush;
            }
            if ((enemyhullstrength < (enemyBaseHull * 0.75)) && (enemyhullstrength >= (enemyBaseHull * 0.25)))
            {
                enemyHullBrush = orangeBrush;
            }
            if (enemyhullstrength < (enemyBaseHull * 0.25))
            {
                enemyHullBrush = redBrush;
            }
            if ((enemyarmorStrength < (enemyBaseArmor * 0.75)) && (enemyarmorStrength >= (enemyBaseArmor * 0.25)))
            {
                enemyArmorBrush = orangeBrush;
            }
            if (enemyarmorStrength < (enemyBaseArmor * 0.25))
            {
                enemyArmorBrush = redBrush;
            }
            if ((enemyShieldStrength < (enemyBaseShield * 0.75)) && (enemyShieldStrength >= (enemyBaseShield * 0.25)))
            {
                enemyShieldBrush = orangeBrush;
            }
            if (enemyShieldStrength < (enemyBaseShield * 0.25))
            {
                enemyShieldBrush = redBrush;
            }
            #endregion
            // MessageBox.Show(string.Format("Damage Suffered: Hull {0} - Armor {1} - Shield {2}\nRemaining: Hull {3} - Armor {4} - Shield {5}\nHit For:{6}", HULL_DAMAGE_SUFFERED, ARMOR_DAMAGE_SUFFERED, SHIELD_DAMAGE_SUFFERED, hullStrength, armorStrength, shieldStrength, enemyRawDamage));

            ScreenRefresh();
        }

        private void shieldSelectComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            resetCombatSim();
            ScreenRefresh();
        }

        private void EnemyShieldComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            resetCombatSim();
            ScreenRefresh();
        }

        private void resetCombatButton_Click(object sender, EventArgs e)
        {
            resetCombatSim();
        }

        private void resetCombatSim()
        {
            SHIELD_DAMAGE_SUFFERED = 0;
            HULL_DAMAGE_SUFFERED = 0;
            ARMOR_DAMAGE_SUFFERED = 0;
            ENEMY_SHIELD_DAMAGE_SUFFERED = 0;
            ENEMY_HULL_DAMAGE_SUFFERED = 0;
            ENEMY_ARMOR_DAMAGE_SUFFERED = 0;
            roundsDone = 0;
            standardHullBrush = greenBrush;
            standardArmorBrush = greenBrush;
            standardShieldBrush = greenBrush;
            enemyHullBrush = greenBrush;
            enemyArmorBrush = greenBrush;
            enemyShieldBrush = greenBrush;
            hullDown = false;
            armorDown = false;
            shieldDown = false;
            enemyhullDown = false;
            enemyarmorDown = false;
            enemyshieldDown = false;
            ScreenRefresh();
        }

        private void hullFortComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (hullFortComboBox.SelectedIndex == 0)
            {
                hullfortBonus = 1;
            }
            if (hullFortComboBox.SelectedIndex == 1)
            {
                hullfortBonus = 0.8;
            }
            if (hullFortComboBox.SelectedIndex == 2)
            {
                hullfortBonus = 0.6;
            }
            resetCombatSim();
            ScreenRefresh();
        }

        private void shieldPoweringComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (shieldPoweringComboBox.SelectedIndex == 0)
            {
                shieldPowbonus = 1;
            }
            if (shieldPoweringComboBox.SelectedIndex == 1)
            {
                shieldPowbonus = 0.75;
            }
            if (shieldPoweringComboBox.SelectedIndex == 2)
            {
                shieldPowbonus = 0.5;
            }
            resetCombatSim();
            ScreenRefresh();
        }

        private void enemyHullFortComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (enemyHullFortComboBox.SelectedIndex == 0)
            {
                enemyHullFortBonus = 1;
            }
            if (enemyHullFortComboBox.SelectedIndex == 1)
            {
                enemyHullFortBonus = 0.8;
            }
            if (enemyHullFortComboBox.SelectedIndex == 2)
            {
                enemyHullFortBonus = 0.6;
            }
            resetCombatSim();
            ScreenRefresh();
        }

        private void enemyShieldPoweringComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (enemyShieldPoweringComboBox.SelectedIndex == 0)
            {
                enemyShieldPowBonus = 1;
            }
            if (enemyShieldPoweringComboBox.SelectedIndex == 1)
            {
                enemyShieldPowBonus = 0.75;
            }
            if (enemyShieldPoweringComboBox.SelectedIndex == 2)
            {
                enemyShieldPowBonus = 0.5;
            }
            resetCombatSim();
            ScreenRefresh();
        }

        private void SmaatForm_Load(object sender, EventArgs e)
        {
            standardHullBrush = greenBrush;
            standardArmorBrush = greenBrush;
            standardShieldBrush = greenBrush;
            enemyHullBrush = greenBrush;
            enemyArmorBrush = greenBrush;
            enemyShieldBrush = greenBrush;
            ArmorComboBox.Text = "Conventional";
            enemyArmorComboBox.Text = "Conventional";
            multiplierComboBox.Text = "1";
            enemyMultiplierComboBox.Text = "1";
            shipSelectBox.Text = "- Sabre";
            enemyShipComboBox.Text = "- Sabre";
            numberOfRoundsComboBox.Text = "1";
            enemyHitRatioTextBox.Text = "10";
            yourHitRatioTextBox.Text = "10";

            redrawTimer.Enabled = true;
        }

        private void redrawTimer_Tick(object sender, EventArgs e)
        {
            ScreenRefresh();
        }
    }
}
